﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Description;
using DailyPhoto.Common;
using DailyPhoto.Common.Services;

namespace DailyPhoto
{

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class DailyPhotoExternalService : IDailyPhoto
    {

        private ServiceHost svc;
        private int port;
        private PrivateThreadPool thpool;

        public DailyPhotoExternalService(int port)
        {
            this.port = port;
            this.thpool = new PrivateThreadPool(1);
        }

        public void Start()
        {
            this.svc = new ServiceHost(this);
            var bind = new NetNamedPipeBinding();
            bind.MaxReceivedMessageSize = 1024 * 1024 * 10;
            bind.ReaderQuotas.MaxArrayLength = 1024 * 1024 * 10;
            bind.MaxBufferSize = 1024 * 1024 * 10;
            bind.ReaderQuotas.MaxStringContentLength = 1024 * 1024 * 10;
            bind.ReceiveTimeout = new TimeSpan(TimeSpan.TicksPerHour * 6);

            var contractType = GetType().GetInterfaces().First();
            this.svc.AddServiceEndpoint(contractType,
                                        bind,
                                        "net.pipe://localhost/dailyphoto");


            var bind2 = new NetTcpBinding(SecurityMode.None);
            bind2.MaxReceivedMessageSize = 1024 * 1024 * 10; // 100M
            bind2.ReaderQuotas.MaxArrayLength = 1024 * 1024 * 10;
            bind2.MaxBufferSize = 1024 * 1024 * 10;
            bind2.ReaderQuotas.MaxStringContentLength = 1024 * 1024 * 10;
            bind2.ReceiveTimeout = new TimeSpan(TimeSpan.TicksPerHour * 6);
            bind2.ReliableSession.InactivityTimeout = new TimeSpan(TimeSpan.TicksPerHour * 6);
            this.svc.AddServiceEndpoint(contractType,
                                       bind2,
                                       string.Format("net.tcp://localhost:{0}/dailyphoto", port));


            this.svc.Description.Behaviors.Add(new ServiceMetadataBehavior());
            this.svc.AddServiceEndpoint(typeof(IMetadataExchange),
                                    MetadataExchangeBindings.CreateMexTcpBinding(),
                                    string.Format("net.tcp://localhost:{0}/dailyphoto/mex", port));

            this.svc.Open();

            Logger.Write("Listening on port {0}",port);
        }

        public void Stop()
        {
            if (svc != null && svc.State != CommunicationState.Closed)
            {
                svc.Close();
            }
            thpool.Dispose();
        }

        public void GeneratePhoto()
        {
            Logger.Write("External service daily photo generation started");
            thpool.Enqueue(Util.GenerateDailyPhoto);
        }
    }


}
